package com.palmgo.utils.drawer.basic;

import org.json.JSONArray;
import org.json.JSONObject;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * 为此app定制的json解析类
 *
 * @author tanqiyong
 */
public class JSON2BeanUtils {
    /**
     * 使用getField，getDeclaredField从CLASS中选出key
     *
     * @param t
     * @param key
     * @return
     */
    private static Field getField(Class<?> t, String key) {
        try {
            if (t == null || isEmpty(key)) {
                return null;
            }
            return t.getField(key);
        } catch (Exception e) {
            try {
                return t.getDeclaredField(key);
            } catch (NoSuchFieldException e1) {
            }
        }
        return null;
    }

    public static <T> T comperJson2Bean(JSONObject json, Class<T> t) {
        try {
            if (t == null || json == null) {
                return null;
            }
            T bean = t.newInstance();
            Iterator<String> keys = json.keys();
            while (keys.hasNext()) {
                try {
                    String key = keys.next();
                    String val = json.optString(key);
                    Field field = getField(t, key);
                    if (field == null) continue;
                    field.setAccessible(true);
                    Class<?> fType = field.getType();
                    // 基本类型的数据
                    if (fType.equals(String.class)) {
                        field.set(bean, val);
                    } else if (fType.equals(int.class)
                            || fType.equals(Integer.class)) {
                        field.set(bean, Integer.valueOf(val));
                    } else if (fType.equals(float.class)
                            || fType.equals(Float.class)) {
                        field.set(bean, Float.valueOf(val));
                    } else if (fType.equals(double.class)
                            || fType.equals(Double.class)) {
                        field.set(bean, Double.valueOf(val));
                    } else if (fType.equals(long.class)
                            || fType.equals(Long.class)) {
                        field.set(bean, Long.valueOf(val));
                    }
                    // 找到这个映射需要包装的字段，然后对数据进行包装
                    BeanReflect reflect = field
                            .getAnnotation(BeanReflect.class);
                    if (reflect == null)
                        continue;
                    Field childField = getField(t, reflect.to());
                    childField.setAccessible(true);
                    String c_key = reflect.key();
                    String c_chld = reflect.childNode();
                    Class<?> c_Clz = reflect.format();
                    // 如果是集合
                    if (childField.getType().equals(List.class)
                            || childField.getType().equals(ArrayList.class)) {
                        if (!isEmpty(c_key)) {
                            JSONObject j = new JSONObject(val);
                            if (j.opt(c_key).getClass() == JSONArray.class) {
                                // 说明列表里有多个
                                childField.set(
                                        bean,
                                        comperJson2List(j.optJSONArray(c_key),
                                                c_Clz));
                            } else {
                                // 说明列表里只有一个
                                if (String.class == c_Clz) {
                                    ArrayList<String> a = new ArrayList<String>();
                                    a.add(j.optString(c_key));
                                    childField.set(bean, a);
                                }else{

                                    ArrayList<Object> a = new ArrayList<Object>();
                                    a.add(comperJson2Bean(j.optJSONObject(c_key), c_Clz));
                                    childField.set(bean, a);
                                }
                            }
                        } else {
                            childField.set(bean,
                                    comperJson2List(new JSONArray(val), c_Clz));
                        }
                    } else {
                        if (!isEmpty(c_key)) {
                            childField.set(
                                    bean,
                                    comperJson2Bean(new JSONObject(val)
                                            .optJSONObject(c_key), c_Clz));
                        } else {
                            childField
                                    .set(bean,
                                            comperJson2Bean(
                                                    new JSONObject(val), c_Clz));
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }

            }
            return bean;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static <T> List<T> comperJson2List(JSONArray jsons, Class<T> t) {
        try {
            if (jsons == null || jsons.length() == 0 || t == null) {
                return null;
            }
            List<T> list = new ArrayList<T>();
            Class<?> jt = jsons.opt(0).getClass();
            // 如果jsons的类型为string，直接拼面stringlist
            if (jt.equals(String.class)) {
                for (int i = 0; i < jsons.length(); i++) {
                    list.add((T) jsons.opt(i));
                }
                return list;
            }
            for (int i = 0; i < jsons.length(); i++) {
                list.add(comperJson2Bean(jsons.getJSONObject(i), t));
            }
            return list;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 将json数据封装入object对象中
     *
     * @param json
     * @param bean
     */
    public static int comperJson2Object(JSONObject json, Object bean) {
        try {
            if (json == null) {
                return -1;
            }
            Iterator<String> keys = json.keys();
            while (keys.hasNext()) {
                String key = keys.next();
                try {
                    Field f = getField(bean.getClass(), key);
                    f.setAccessible(true);
                    BeanReflect br = f.getAnnotation(BeanReflect.class);
                    JSONArray data = json.optJSONObject(key).optJSONArray(
                            br.childNode());
                    f.set(bean, comperJson2List(data, br.format()));
                    return json.optJSONObject(key).optInt("version");
                } catch (Exception e) {
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return -1;
    }
    public static  boolean isEmpty(String str){
        return str==null || "".equals(str) || "".equals(str.trim());
    }
}
